🤖 fix: make generated CRD API docs YAML-oriented#59
Conversation
|
@codex review Please review this docs-generation change. |
ff7f500 to
b65e3d6
Compare
|
@codex review Addressed docs-quality markdownlint failures from CI and force-pushed updates. |
|
Codex Review: Didn't find any major issues. Nice work! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
b65e3d6 to
c55b318
Compare
|
@codex review Added cspell allowlist entry for the new |
|
Codex Review: Didn't find any major issues. Delightful! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
Summary
Improves generated CRD API reference docs so they read more like YAML users actually write, with cleaner field/type names and selective nested-object expansion for actionable object fields.
Background
The generated docs were hard to use because table keys repeated
spec./status., type names included noisy fully-qualified package paths, and object-like fields (for exampleLocalObjectReference) did not show nested members users need in YAML.Implementation
hack/crd-ref-docs/templates/markdown/gv_list.tpl:spec./status.prefixes from table rows.metav1,corev1, and local API types).renderFieldstemplate for nested field expansion.corev1.LocalObjectReferencewith depth limit 3 to avoid doc bloat.docs/reference/api/*.md.Validation
make verify-vendormake testmake buildmake lintmake docs-referencemake docs-checkRisks
Low to moderate. This changes only documentation generation templates and generated markdown output, not runtime behavior. Main risk is doc rendering regressions; mitigated by successful
make docs-check(strict mkdocs build) and regeneration checks.📋 Implementation Plan
Plan: Make CRD API reference docs read like YAML (nested + less verbose)
Context / Why
The current generated API reference docs (e.g.
docs/reference/api/coderprovisioner.md) are hard for users to act on:spec./status.even though the table is already under## Spec/## Status.controlPlaneRefis acorev1.LocalObjectReference, but the docs don’t show that the YAML must containname:). Users don’t know what to write.Goal: adjust the
crd-ref-docsmarkdown template so the output is:LocalObjectReference).Evidence (what we verified)
crd-ref-docsviahack/update-reference-docs.sh/make docs-reference. (hack/update-reference-docs.sh,hack/crd-ref-docs/config.yaml)hack/crd-ref-docs/templates/markdown/gv_list.tpl.docs/reference/api/coderprovisioner.md.crd-ref-docsrepresents nested types viatypes.Typewith aMembers()method that returns struct fields even through aliases/slices/pointers. (vendor/github.com/elastic/crd-ref-docs/types/types.go)Implementation details
1) Remove redundant
spec./status.prefixesFile:
hack/crd-ref-docs/templates/markdown/gv_list.tpl## Specfrom:to:
## Statusfrom:to:
Result: tables read like the YAML keys a user will set under
spec:/status:.2) Bonus: Clean up verbose Go type paths in the
TypecolumnFile:
hack/crd-ref-docs/templates/markdown/gv_list.tpl(thetypeNamehelper)Update
typeNameto replace noisy package paths with common aliases / short names.Proposed replacements (minimal, focused on what we see in our CRDs):
k8s.io/apimachinery/pkg/apis/meta/v1.→metav1.(already present)k8s.io/api/core/v1.→corev1.github.com/coder/coder-k8s/api/v1alpha1.→ `` (strip to just the type name)Shape:
{{- $typeString := $fieldType.String -}} {{- $typeString = trimPrefix "*" $typeString -}} {{- $typeString = $typeString | replace "k8s.io/apimachinery/pkg/apis/meta/v1." "metav1." -}} {{- $typeString = $typeString | replace "k8s.io/api/core/v1." "corev1." -}} {{- $typeString = $typeString | replace "github.com/coder/coder-k8s/api/v1alpha1." "" -}} {{- $typeString -}}Result: types become readable (
corev1.LocalObjectReference,CoderProvisionerKeySpec, etc.) without losing meaning.3) Show nested fields for selected “object” types (so users know what to write)
File:
hack/crd-ref-docs/templates/markdown/gv_list.tplReplace the flat
range $specMembers/range $statusMembersrendering with a small recursive renderer that can optionally expand struct members.3.1) Expansion policy (avoid doc bloat)
We should not blindly expand every imported Kubernetes type (e.g.
corev1.EnvVarcan recursively explode). Instead, expand only when:len $t.Members > 0), and$t.Packagestarts withgithub.com/coder/coder-k8s/api/), ork8s.io/api/core/v1.LocalObjectReference.Add a simple depth limit (e.g.
maxDepth := 3) to prevent runaway recursion.3.2) Table rendering shape
Add a new template block (name is flexible) that prints rows for a list of fields and can recurse:
{{- define "renderFields" -}} {{- $fields := index . 0 -}} {{- $depth := index . 1 -}} {{- $maxDepth := index . 2 -}} {{- $indent := repeat $depth " " -}} {{- range $f := $fields }} {{- if not $f.Type -}} {{ fail (printf "field %q is missing type information" $f.Name) }} {{- end -}} {{- $t := $f.Type -}} {{- $hasMembers := gt (len $t.Members) 0 -}} {{- $isProjectLocal := hasPrefix $t.Package "github.com/coder/coder-k8s/api/" -}} {{- $isLocalObjectRef := and (eq $t.Package "k8s.io/api/core/v1") (eq $t.Name "LocalObjectReference") -}} {{- $shouldExpand := and $hasMembers (lt $depth $maxDepth) (or $isProjectLocal $isLocalObjectRef) -}} | {{ $indent }}`{{ $f.Name }}` | `{{ template "typeName" $t }}` | {{ markdownRenderFieldDoc $f.Doc }} | {{- if $shouldExpand }} {{- template "renderFields" (list $t.Members (add $depth 1) $maxDepth) -}} {{- end }} {{- end }} {{- end -}}Then render spec/status like:
Result: users will see
controlPlaneRef→name(and other small structs) directly in the table, without needing to understand Go types.Why this policy (and not “expand everything”)?
Expanding every imported Kubernetes type tends to create huge, hard-to-navigate pages and slows review. The hybrid approach targets the worst UX offenders (object refs and project-local structs) while keeping common K8s “implementation detail” structs as a single row.
Follow-up options if we want more detail later:
metav1.LabelSelector),<details>blocks instead of in-table recursion,4) Regenerate reference docs and confirm output
After template changes, regenerate docs so the repo reflects the new format.
make docs-reference(orbash hack/update-reference-docs.sh)docs/reference/api/coderprovisioner.mdno longer hasspec./status.prefixes.controlPlaneRefexpands to showname.mkdocs.ymlnav updates (if the script touches it).Validation
make docs-reference(ensures generator + templates work and output is updated)make docs-check(ensures the docs site still builds)make test(sanity check; should be unchanged but cheap to verify)Generated with
mux• Model:openai:gpt-5.3-codex• Thinking:xhigh• Cost: $0.53